package org.vacoor.xqq.ui.comp.tabpane;

import org.vacoor.xqq.ui.util.UIs;

import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import java.awt.*;
import java.awt.event.*;

/**
 * User: vacoor
 */
public class FlatTabbedPaneUI extends BasicTabbedPaneUI {
    //    private Color tabBorderColor = new Color(0xD4E2E3);
    private Color tabBorderColor = new Color(0xD4D7E3);
    private Color tabSelectedColor;
    private Handler handler;


    public static ComponentUI createUI(JComponent c) {
        return new FlatTabbedPaneUI();
    }

    protected void initDefaults() {
        UIManager.put("TabbedPane.font", UIs.getBestFont());
        UIManager.put("TabbedPane.tabAreaInsets", new Insets(0, 15, 0, 0)); // 标签区域的 margin
        UIManager.put("TabbedPane.tabInsets", new Insets(0, 5, 0, 5));  // 标签内容 margin
        UIManager.put("TabbedPane.selectedTabPadInsets", new Insets(0, 0, 0, 0));
//        UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 15, 15, 15));
        UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 5, 15, 5));
//        UIManager.put("TabbedPane.foreground", new Color(0xB0B1B3));
//        UIManager.put("TabbedPane.foreground", Color.WHITE);
        UIManager.put("TabbedPane.selectedForeground", new Color(0xE6E7E9));
//        UIManager.put("TabbedPane.tabAreaBackground", Color.WHITE);
//        UIManager.put("TabbedPane.contentAreaColor", Color.WHITE);


        UIManager.put("TabbedPane.background", new Color(0xFCFEFB)); // 背景色
//        UIManager.put("TabbedPane.background", new Color(0x16A086)); // 背景色
//        UIManager.put("TabbedPane.selected", new Color(0x739E73)); // 选中标签背景色
        UIManager.put("TabbedPane.selected", new Color(0x5C9A2D)); // 选中标签背景色

        UIManager.put("TabbedPane.focus", false);
        UIManager.put("TabbedPane.opaque", false);
        UIManager.put("TabbedPane.tabsOpaque", false);
        UIManager.put("TabbedPane.contentOpaque", false);
//        UIManager.put("TabbedPane.tabsOverlapBorder", false);
//        UIManager.put("TabbedPane.tabRunOverlay", 10);

    }

    @Override
    protected void installDefaults() {
        initDefaults();
        tabSelectedColor = UIManager.getColor("TabbedPane.selected");
        super.installDefaults();
    }

    @Override
    protected void installListeners() {
        if (tabPane instanceof QuickOpTabbedPane) {
            tabPane.addMouseListener(getHandler());
            tabPane.addComponentListener(getHandler());
        }
//        ActionMap am = tabPane.getActionMap();
        /*
        am.put("QuickOpTabbedPane.nextTab", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(tabPane == null || tabPane.getTabCount() < 2) {
                    return;
                }
                int idx = tabPane.getSelectedIndex();
                tabPane.setSelectedIndex(idx < tabPane.getTabCount() - 1 ? idx : 0);
            }
        });
        */

//        SwingUtilities.replaceUIActionMap(tabPane, am);

        super.installListeners();
    }


    @Override
    protected LayoutManager createLayoutManager() {
        /*
        if (tabLayoutPolicy == QuickOpTabbedPane.FILL_TAB_LAYOUT) {
            return new TabbedPaneLayout();
        }else {
        */
        // 父已经处理
        return super.createLayoutManager();
        /*
        }
        */
    }

    @Override
    protected void setRolloverTab(int index) {
        super.setRolloverTab(index);
        // 当鼠标移动到 Tab 时, 重绘, 主要是为了 Rollover 效果
        if (tabPane.isVisible()) {
            tabPane.repaint();
        }
    }

    @Override
    protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {

//        g.setColor(!isSelected || selectedColor == null?
        Color oldColor = g.getColor();
        Graphics2D g2d = (Graphics2D) g;
        g.setColor(!isSelected || tabSelectedColor == null ? tabPane.getBackgroundAt(tabIndex) : tabSelectedColor);

//        if (isSelected) {
//            selectedColor = selectedColor != null ? selectedColor : tabPane.getComponentAt(tabIndex).getBackground();
//            g.setColor(selectedColor);
//        }

        g2d.fillRect(x, y, w, h);
        g2d.setColor(oldColor);
    }

    @Override
    protected void paintText(Graphics g, int tabPlacement, Font font, FontMetrics metrics, int tabIndex, String title, Rectangle textRect, boolean isSelected) {
        super.paintText(g, tabPlacement, font, metrics, tabIndex, title, textRect, isSelected);
    }

    /**
     * 绘制 Tab 边框
     */
    @Override
    protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
        Color oldColor = g.getColor();
        g.setColor(tabBorderColor);
//        if(!isSelected) {
        g.drawLine(x, y, x, y + h - 1); // LEFT
        g.drawLine(x + w, y, x + w, y + h - 1); // RIGHT
//        }

        if (!isSelected) {
//            g.drawLine(x, y, x + w, y); //TOP
            g.drawLine(x, y + h - 1, x + w, y + h - 1); // BOTTOM
        }
        g.setColor(oldColor);
    }

    /**
     * 绘制内容边框
     */
    @Override
    protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
    }

    /**
     * 绘制焦点
     */
    @Override
    protected void paintFocusIndicator(Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect, boolean isSelected) {
    }

    @Override
    protected int getTabLabelShiftX(int tabPlacement, int tabIndex, boolean isSelected) {
        return 0;
    }

    protected int getTabLabelShiftY(int tabPlacement, int tabIndex, boolean isSelected) {
        return 0;
    }

    @Override
    protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics) {
        int tabCount = tabPane.getTabCount();

        // 1 个标签页直接隐藏
        if ((LEFT == tabPlacement || RIGHT == tabPlacement) && tabCount < 2) {
            return 0;
        }

        if (QuickOpTabbedPane.FILL_TAB_LAYOUT == tabPane.getTabLayoutPolicy() && (TOP == tabPlacement || BOTTOM == tabPlacement)) {
            int tabAreaWidth = calculateTabAreaSize().width;
            int avgWidth = tabAreaWidth / tabCount;
            return tabCount - 1 > tabIndex ? avgWidth : tabAreaWidth - (tabCount - 1) * avgWidth;
        }

        int w = super.calculateTabWidth(tabPlacement, tabIndex, metrics);

        // 在顶部和底部最小宽度为20
        if ((TOP == tabPlacement || BOTTOM == tabPlacement) && w < 20) {
            w = 20;
        }
        return w;
    }

    @Override
    protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight) {
        int tabCount = tabPane.getTabCount();

        if ((TOP == tabPlacement || BOTTOM == tabPlacement) && tabCount < 2) {
            return 0;
        }

        if ((LEFT == tabPlacement || RIGHT == tabPlacement) && QuickOpTabbedPane.FILL_TAB_LAYOUT == tabPane.getTabLayoutPolicy()) {
            int tabAreaHeight = calculateTabAreaSize().height;
            int avgHeight = tabAreaHeight / tabCount;
            return tabCount - 1 > tabIndex ? avgHeight : tabAreaHeight - (tabCount - 1) * avgHeight;
        }

        int h = super.calculateTabHeight(tabPlacement, tabIndex, fontHeight) - 2;
        if ((LEFT == tabPlacement || RIGHT == tabPlacement) && h < 20) {
            h = 20;
        }
        return h;
    }

    /**
     * @return
     */
    protected Dimension calculateTabAreaSize() {
        int tabPlacement = tabPane.getTabPlacement();
        Insets tabPaneInsets = tabPane.getInsets();
        Insets contentInsets = getContentBorderInsets(tabPlacement);
        Insets tabAreaInsets = getTabAreaInsets(tabPlacement);

        int width = 0, height = 0;  // tabPane
        int cWidth = 0, cHeight = 0; // 组件

        // 找到最大的组件
        for (int i = 0; i < tabPane.getTabCount(); i++) {
            Component component = tabPane.getComponentAt(i);
            if (component != null) {
                // 首选 Size
                Dimension size = component.getSize();
                if (size.width == 0 || size.height == 0) {
                    size = component.getPreferredSize();
                }

                if (size != null) {
                    cWidth = Math.max(size.width, cWidth);
                    cHeight = Math.max(size.height, cHeight);
                }
            }
        }

        width += cWidth;
        height += cHeight;

        width += contentInsets.left + contentInsets.right;
        height += contentInsets.top + contentInsets.bottom;

        width -= tabAreaInsets.left + tabAreaInsets.right;
        height -= tabAreaInsets.top + tabAreaInsets.bottom;
        return new Dimension(width, height);
    }

    @Override
    protected void installKeyboardActions() {
        super.installKeyboardActions();

        if (tabPane instanceof QuickOpTabbedPane) {
            ActionMap am = tabPane.getActionMap();
            InputMap inputMap = tabPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

            am.put("QuickOpTabbedPane.nextTab", new TabSwitchAction(TabSwitchAction.NEXT));
            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.ALT_DOWN_MASK), "QuickOpTabbedPane.nextTab");

            am.put("QuickOpTabbedPane.preTab", new TabSwitchAction(TabSwitchAction.PRE));
            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_P, KeyEvent.ALT_DOWN_MASK), "QuickOpTabbedPane.preTab");
            for (int i = 1; i < 10; i++) {
                String action = "QuickOpTabbedPane.tab" + i;
                am.put(action, new TabSwitchAction(i - 1));
                inputMap.put(KeyStroke.getKeyStroke(48 + i, KeyEvent.ALT_DOWN_MASK), action);
            }
        }
    }

    // -------------------------
    private class TabSwitchAction extends AbstractAction {
        private static final int NEXT = -1;
        private static final int PRE = -2;
        public int index;

        public TabSwitchAction(int idx) {
            this.index = idx;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (tabPane == null || tabPane.getTabCount() < 2 || !(tabPane instanceof QuickOpTabbedPane) || !((QuickOpTabbedPane)tabPane).isEnabledTabQuickSwitch()) {
                return;
            }
            int idx = tabPane.getSelectedIndex();
            if (NEXT == index && idx > -1) {
                idx++;
                tabPane.setSelectedIndex(idx < tabPane.getTabCount() ? idx : 0);
            } else if (PRE == index && idx > -1) {
                idx--;
                tabPane.setSelectedIndex(idx > -1 ? idx : tabPane.getTabCount() - 1);
            } else if (index > -1 && index < tabPane.getTabCount()) {
                tabPane.setSelectedIndex(index);
            }
        }
    }

    private Handler getHandler() {
        if (handler != null) {
            return handler;
        }
        return handler = new Handler();
    }

    private class Handler extends ComponentAdapter implements MouseListener {

        @Override
        public void componentResized(ComponentEvent e) {
            if (tabPane != null && tabPane.isVisible() && QuickOpTabbedPane.FILL_TAB_LAYOUT == tabPane.getTabLayoutPolicy()) {
                tabPane.repaint();
            }
        }

        @Override
        public void mouseClicked(MouseEvent e) {
            // 晕, 传递给它的 tabPane 没有用, 用的是自己维护的
            if (tabPane == null || !(tabPane instanceof QuickOpTabbedPane) || !((QuickOpTabbedPane) tabPane).isEnabledTabDBClickClose()) {
                return;
            }
            int i = tabForCoordinate(tabPane, e.getX(), e.getY());
            if (-1 != i && SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 1) {
                tabPane.removeTabAt(i);
            }
        }

        @Override
        public void mousePressed(MouseEvent e) {
        }

        @Override
        public void mouseReleased(MouseEvent e) {
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseExited(MouseEvent e) {
        }
    }
}
